<template>
  <div class="table-box">
    <el-button type="primary" @click="addRow">添加一条</el-button>
    <el-button type="primary" @click="submit(ruleFormRef)">提交</el-button>
    <el-switch v-model="entryMode" class="mb-2" active-text="单机获取复制焦点、双击唤醒输入框" inactive-text="点击唤醒输入框" />
    <el-form ref="ruleFormRef" :model="ruleForm" class="demo-ruleForm">
      <el-table
        border
        :data="ruleForm.tableData"
        :columns="columns"
        size="normal"
        @paste.native="pasteInfo($event)"
        @row-dblclick="onDoubleClickRow"
        @cell-click="cellClick"
        @header-click="headerClick"
        :highlight-current-row="true"
      >
        <el-table-column v-for="(item, index) in columns" :key="index" :prop="item.key" :label="item.label" :data-index="index">
          <template #header="{ column, $index }">
            <span class="column-header"><i v-if="item.isCheck">*</i>{{ item.label }}</span>
          </template>
          <template #default="{row, $index}">
            <!-- 需要校验 -->
            <el-form-item
              v-if="$index >= 0 && item.key !== '' && item.isCheck"
              :prop="`tableData.${$index}.${item.key}`"
              :rules="[{ required: true, validator: validateNode, trigger: 'blur' }]"
            >
              <el-tooltip placement="bottom" :content="row.isError[item.key].msg" effect="light" v-if="row.isError[item.key].msg !== ''">
                <div v-if="!row.isEdit && item.type !== 'NONE'" class="table-text" :class="!row.isError[item.key].status ? 'error' : ''">
                  <span class="text">{{ row[item.key] || '--' }}</span>
                  <el-icon><EditPen /></el-icon>
                </div>
                <div class="table-text" v-if="row.isEdit && item.type !== 'NONE'">
                  <base-form :columnData="item" :itemData="row"></base-form>
                </div>
              </el-tooltip>
              <template v-if="row.isError[item.key].msg === ''">
                <div v-if="!row.isEdit && item.type !== 'NONE'" class="table-text" :class="!row.isError[item.key].status ? 'error' : ''">
                  <span class="text">{{ row[item.key] || '--' }}</span>
                  <el-icon><EditPen /></el-icon>
                </div>
                <div class="table-text" v-if="row.isEdit && item.type !== 'NONE'">
                  <base-form :columnData="item" :itemData="row"></base-form>
                </div>
              </template>
            </el-form-item>
            <!-- 不需要校验 -->
            <template v-if="$index >= 0 && item.key !== '' && !item.isCheck">
              <div v-if="!row.isEdit && item.type !== 'NONE'" class="table-text">
                <span class="text">{{ row[item.key] || '--' }}</span>
                <el-icon><EditPen /></el-icon>
              </div>
              <div class="table-text" v-if="row.isEdit && item.type !== 'NONE'">
                <base-form :columnData="item" :itemData="row"></base-form>
              </div>
            </template>
            <el-button v-if="item.type === 'NONE'" type="info" link @click.stop="saveRow(row, item)">
              确定
            </el-button>
            <el-button v-if="item.type === 'NONE'" type="info" link @click.stop="delRow(row, item)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>

<script setup>
import { nextTick, ref } from 'vue'
import baseForm from './baseForm.vue'
const entryMode = ref(false)

// 表单
const ruleFormRef = ref(0)
const ruleForm = ref({
  tableData: []
})
const validateNode = (rule, value, callback) => {
  let start = rule.field.lastIndexOf('.')
  let key = rule.field.slice(start + 1, rule.field.length)
  let index = Number(rule.field.replace(/[^\d]/g, ' '))
  if (value === '') {
    ruleForm.value.tableData[index].isError[key].status = false
    ruleForm.value.tableData[index].isError[key].msg = '不能为空，请输入'
    callback(new Error('不能为空，请输入'))
  } else if (value.length >= 10) {
    ruleForm.value.tableData[index].isError[key].status = false
    ruleForm.value.tableData[index].isError[key].msg = '字数过多，最大输入10位'
    callback(new Error('字数过多，最大输入10位'))
  } else {
    ruleForm.value.tableData[index].isError[key].status = true
    ruleForm.value.tableData[index].isError[key].msg = ''
    callback()
  }
}

// 提交表格
const submit = async (formEl) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
    } else {
    }
  })
}
// 复制表格

const tableData = ref([
  {
    name: '李阿斯顿',
    age: 14,
    status: '是',
    isEdit: false,
    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  },
  {
    name: '李顿',
    age: 24,
    status: '否',
    isEdit: false,
    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  }
])
const emptyObj = ref({
  //全部列都可以粘贴
  // name: undefined,
  // age: undefined,
  // status: undefined
})
const defaultEmptyObj = ref({})
const currentRowIndex = ref(undefined)
const currentColumnIndex = ref(undefined)
const currentColumnKey = ref(undefined)
const rowsInfo = ref([])
const columns = ref([
  {
    key: 'name',
    label: '姓名',
    align: 'center',
    isCheck: true,
    type: 'TEXT'
  },
  {
    key: 'age',
    label: '年龄',
    align: 'center',
    isCheck: true,
    type: 'TEXT'
  },
  {
    key: 'status',
    label: '状态',
    align: 'center',
    isCheck: false,
    type: 'SELECT'
  },
  {
    key: '',
    label: '操作',
    align: 'center',
    type: 'NONE'
  }
])
const pasteInfo = (e) => {
  nextTick(() => {
    try {
      let isEdit = false
      ruleForm.value.tableData.forEach((item) => {
        if (item.isEdit) {
          isEdit = item.isEdit
        }
      })
      if (isEdit) {
        return
      }
      var data = null
      var clipboardData = e.clipboardData // IE
      if (!clipboardData) {
        //chrome
        clipboardData = e.originalEvent.clipboardData
      }
      //复制过来的内容
      data = clipboardData.getData('Text')
      //首先对源头进行解析
      var rowStrArray = data.split('\n') //拆成很多行
      rowsInfo.value = []
      emptyObj.value = {}
      defaultEmptyObj.value = {}
      for (var i = 0; i < rowStrArray.length - 1; i++) {
        var row = []
        var tdStrArray = rowStrArray[i].split('\t') //按列拆分
        for (var j = 0; j < tdStrArray.length; j++) {
          row.push(tdStrArray[j])
        }
        rowsInfo.value.push(row)
      }

      let columnslastIndex = rowsInfo.value[0].length - 1
      let columnsfirstIndex = columns.value.findIndex((item) => currentColumnKey.value == item.key)
      columns.value.map((item, index) => {
        let objkey = { [item.key]: undefined }
        if (index >= columnsfirstIndex && item.key !== '') {
          emptyObj.value = { ...emptyObj.value, ...objkey }
        }
        if (item.key !== '') {
          defaultEmptyObj.value = { ...defaultEmptyObj.value, ...objkey }
        }
      })
      let rowList = []
      for (var j = 0; j < rowsInfo.value.length; j++) {
        let temp = {
          isEdit: false,
          isError: {
            name: {
              status: true,
              msg: ''
            },
            age: {
              status: true,
              msg: ''
            },
            status: {
              status: true,
              msg: ''
            }
          }
        }
        let num = 0
        let numFlag = JSON.parse(JSON.stringify(currentColumnIndex.value))
        for (var key in emptyObj.value) {
          if (!rowsInfo.value[j][num]) {
            break
          }
          if (currentColumnIndex.value <= numFlag) {
            temp[key] = rowsInfo.value[j][num]
            num = num + 1
          }
          numFlag = numFlag + 1
        }
        if (tableData.value[currentRowIndex.value + j]) {
          let item = tableData.value[currentRowIndex.value + j]
          Object.keys(item).forEach((key) => {
            item[key] = temp[key] == undefined ? item[key] : temp[key]
          })
        } else {
          let keyName = {}
          for (var key in defaultEmptyObj.value) {
            if (!temp[key]) {
              keyName[key] = ''
            }
          }
          tableData.value.push({ ...keyName, ...temp })
        }
        rowList.push(temp)
      }
    } catch (err) {
    }
  })
}
ruleForm.value.tableData = tableData.value
const prevRow = ref({})
// const onClickRow = (row, column, event) => {}

const clipboardlistFalg = ref(false) // 处理复制到输入框 还是复制循环到表格

// 当某一行被双击时会触发该事件
const onDoubleClickRow = (row, column, event) => {
  if (prevRow.value.isEdit) {
    prevRow.value.isEdit = false
  }
  row.isEdit = true
  prevRow.value = row
  clipboardlistFalg.value = true
}

// 当某个单元格被点击时会触发该事件
const cellClick = (row, column, cell, event) => {
  let rowIndex = tableData.value.findIndex((item) => item === row)
  currentColumnKey.value = column.property
  currentRowIndex.value = rowIndex
  currentColumnIndex.value = column.rawColumnKey
  clipboardlistFalg.value = false
}
// 当某一列的表头被点击时会触发该事件
const headerClick = (column, event) => {
  currentColumnKey.value = column.property
  currentRowIndex.value = tableData.value.length
  currentColumnIndex.value = column.rawColumnKey
  clipboardlistFalg.value = false
}
// 暂存
const saveRow = (row, item) => {
  row.isEdit = false
}
// 删除
const delRow = (row, item) => {
  tableData.value.splice(tableData.value.indexOf(row), 1)
}
// 新增
const addRow = () => {
  tableData.value.push({
    name: '',
    age: '',
    status: '',
    isEdit: true,
    isError: {
      name: {
        status: true,
        msg: ''
      },
      age: {
        status: true,
        msg: ''
      },
      status: {
        status: true,
        msg: ''
      }
    }
  })
  if (prevRow.value.isEdit) {
    prevRow.value.isEdit = false
  }
}
</script>
<style lang="scss">
#app {
  height: 100%;
}
</style>
<style lang="scss" scoped>
.table-box {
  height: 100%;
  margin-top: 0;
  :deep(.el-table) {
    --el-table-current-row-bg-color: #f4f8fe;
    --el-table-row-hover-bg-color: #f4f8fe;

    tr {
      td.el-table__cell {
        padding: 4px 0;
      }
      &:hover {
        .table-text {
          border: var(--el-table-border);
          background: #fff;
          cursor: text;
          .el-icon {
            opacity: 1;
          }
        }
      }
      .column-header {
        i {
          color: var(--el-color-danger);
          margin-right: 4px;
        }
      }
      .el-form-item {
        margin-bottom: 0;
      }
    }
  }
  .table-text {
    width: 100%;
    user-select: none;
    border: 1px solid transparent;
    border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
    transition: all 0.3s;
    // position: relative;
    display: flex;
    align-items: center;
    .text {
      padding-left: 10px;
      flex: 1;
      line-height: 30px;
    }
    .el-icon {
      opacity: 0;
      padding-right: 10px;
      color: var(--el-color-info-light-3);
    }
    &.error {
      // border-color: var(--el-color-danger);
      box-shadow: 0 0 0 1px var(--el-color-danger) inset;
    }
  }
}
</style>
